//
//  WKWebController.m
//  云成绩
//

#import "WKWebController.h"
#import <WebKit/WebKit.h>
#import "UIAlertMaker.h"


NSString * cookieFromURL(NSURL *url) {
    NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    NSMutableString *cookieString = [[NSMutableString alloc] init];
    NSDate *now = [[NSDate alloc] init];
    for (NSHTTPCookie*cookie in [cookieStorage cookies]) {
        if ([cookie.domain isEqualToString:url.host] &&
//            [cookie.name isEqualToString:@"SESSIONID"] &&
            (cookie.expiresDate == nil || now < cookie.expiresDate)) {
            [cookieString appendFormat:@"%@=%@; path=/;",cookie.name,cookie.value];
        }
    }
    return cookieString.length == 0 ? nil : cookieString.copy;
}

@interface WKWebDelegateInstance : NSObject <WKUIDelegate, WKNavigationDelegate>

@property (nonatomic, weak) WKWebController *controller;
@property (nonatomic, readonly) id<WKDelegate> delegate;

@end



@interface WKWebController ()

@property (nonatomic, strong) WKWebDelegateInstance *delegateInstance;
@property (nonatomic, strong) NSMutableArray<__kindof WKWebHandle *> * handles;
@property (nonatomic, assign) CGFloat progressOffset;

@property (nonatomic, strong) NSTimer *progressTimer;

@property (nonatomic, strong) WKUserScript *cookieScript;

@end


#pragma mark - JS交互接口对象
@implementation WKWebHandle

- (instancetype)initWithName:(NSString *)name Target:(id)target Action:(SEL)action {
    self = [super init];
    if (self) {
        self.name = name;
        self.target = target;
        self.action = action;
    }
    return self;
}

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    if (_action == nil) {
//        return NSLog(@"--->error: unknow js interface %@, callback action", _target);
    }
    [_target performSelectorOnMainThread:_action withObject:message.body waitUntilDone:NO];
}

@end

#pragma mark - WebView 加载扩展
@implementation WKWebView (LoadRequest)

- (WKNavigation *)loadMutableRequest:(NSMutableURLRequest *)request useCookie:(NSString *)cookieString {
    NSURL *url = request.URL;
    
    
    WKUserContentController *userController = self.configuration.userContentController;
    NSMutableArray<WKUserScript *> * scripts = userController.userScripts.mutableCopy;
    
    [userController removeAllUserScripts];
    for (WKUserScript *script in scripts) {
        if ([script.source hasPrefix:@"document.cookie="]) continue;
        
        [userController addUserScript:script];
    }
    
    if (cookieString.length > 0) {
        [request setValue:cookieString forHTTPHeaderField:@"Cookie"];
//        [request addValue:cookieString forHTTPHeaderField:@"Cookie"];
        
        WKUserScript *cookieScript = [[WKUserScript alloc] initWithSource:Format(@"document.cookie='%@';",cookieString) injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES];

        [userController addUserScript:cookieScript];
        
        print(@"--->Cookie:%@ URL:%@",cookieString, url);
    } else {
        [request setValue:nil forHTTPHeaderField:@"Cookie"];
    }
    
    objc_setAssociatedObject(self, "current.load.url", url, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
    return [self loadRequest:request];
}

- (WKNavigation *)loadURL:(NSURL *)url {
    return [self loadMutableRequest:[NSMutableURLRequest requestWithURL:url] useCookie:cookieFromURL(url)];
}

@end


#pragma mark - 代理实例
@implementation WKWebDelegateInstance

- (id<WKDelegate>)delegate {
    return _controller.delegate;
}


#pragma mark: - JavaScriptHandle
- (void)onJavaScriptHandleError:(NSString *)message {
    if ([self.delegate respondsToSelector:@selector(onJavaScriptHandleError:)]) {
        return [self.delegate onJavaScriptHandleError:message];
    }
    [UIAlert(UIAlertControllerStyleAlert)
     .title(@"网页错误")
     .message(message)
     .button(@"确定").style(UIAlertActionStyleCancel)
     presentWith:self.controller];
}

- (void)onJavaScriptBackApp:(id)obj {
    if ([self.delegate respondsToSelector:@selector(onJavaScriptBackApp:)]) {
        return [self.delegate onJavaScriptBackApp:obj];
    }
    
    if ([self.controller.webView canGoBack]) {
        [self.controller.webView goBack];
    } else if (self.controller.navigationController) {
        [self.controller.navigationController popViewControllerAnimated:YES];
    } else {
        [self.controller dismissViewControllerAnimated:YES completion:nil];
    }
    
    
}

- (void)onJavaScriptShare:(NSDictionary *)share {
    if ([self.delegate respondsToSelector:@selector(onJavaScriptShare:)]) {
        return [self.delegate onJavaScriptShare:share];
    }
}


#pragma mark: - other
-(void)appOpenURL:(NSURL *)url {
    UIApplication *app = [UIApplication sharedApplication];
    
    if ([app canOpenURL:url])
    {
        [app openURL:url];
    }
}

#pragma mark: - WKUIDelegate

- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler
{
    if ([self.delegate respondsToSelector:@selector(webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:completionHandler:)]) {
        return [self.delegate webView:webView runJavaScriptAlertPanelWithMessage:message initiatedByFrame:frame completionHandler:completionHandler];
    }
    
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:message preferredStyle:UIAlertControllerStyleAlert];
    
    [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        completionHandler();
        
    }]];
    
    [_controller presentViewController:alert animated:YES completion:nil];
}

- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler {
    
    if ([self.delegate respondsToSelector:@selector(webView:runJavaScriptConfirmPanelWithMessage:initiatedByFrame:completionHandler:)]) {
        return [self.delegate webView:webView runJavaScriptConfirmPanelWithMessage:message initiatedByFrame:frame completionHandler:completionHandler];
    }

    UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:message preferredStyle:UIAlertControllerStyleAlert];
    
    [alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(NO);
    }]];
    
    [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(YES);
    }]];
    
    [_controller presentViewController:alert animated:YES completion:nil];
    
}

- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable result))completionHandler {
    
    if ([self.delegate respondsToSelector:@selector(webView:runJavaScriptTextInputPanelWithPrompt:defaultText:initiatedByFrame:completionHandler:)]) {
        return [self.delegate webView:webView runJavaScriptTextInputPanelWithPrompt:prompt defaultText:defaultText initiatedByFrame:frame completionHandler:completionHandler];
    }
    
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:prompt message:nil preferredStyle:UIAlertControllerStyleAlert];
    
    [alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
        textField.placeholder = prompt;
        textField.text = defaultText;
    }];
    
    [alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(nil);
    }]];
    [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(alert.textFields.firstObject.text);
    }]];
    
    [_controller presentViewController:alert animated:YES completion:nil];
}


- (void)webViewDidClose:(WKWebView *)webView API_AVAILABLE(macosx(10.11), ios(9.0)){
    
    if ([self.delegate respondsToSelector:@selector(webViewDidClose:)]) {
        [self.delegate webViewDidClose:webView];
    }
    
}
- (BOOL)webView:(WKWebView *)webView shouldPreviewElement:(WKPreviewElementInfo *)elementInfo API_AVAILABLE(ios(10.0)){

    if ([self.delegate respondsToSelector:@selector(webView:shouldPreviewElement:)]) {
       return [self.delegate webView:webView shouldPreviewElement:elementInfo];
    }
    
    return YES;
}

- (void)webView:(WKWebView *)webView commitPreviewingViewController:(UIViewController *)previewingViewController API_AVAILABLE(ios(10.0)){
    if ([self.delegate respondsToSelector:@selector(webView:commitPreviewingViewController:)]) {
        [self.delegate webView:webView commitPreviewingViewController:previewingViewController];
    }

}

- (nullable UIViewController *)webView:(WKWebView *)webView previewingViewControllerForElement:(WKPreviewElementInfo *)elementInfo defaultActions:(NSArray<id <WKPreviewActionItem>> *)previewActions API_AVAILABLE(ios(10.0)){
    if ([self.delegate respondsToSelector:@selector(webView:previewingViewControllerForElement:defaultActions:)]) {
        return [self.delegate webView:webView previewingViewControllerForElement:elementInfo defaultActions:previewActions];
    }
    return nil;
}

#pragma mark: - WKNavigationDelegate

- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error {
    objc_setAssociatedObject(webView, "current.load.url", nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

    if ([self.delegate respondsToSelector:@selector(webView:didFailNavigation:withError:)]) {
        return [self.delegate webView:webView didFailNavigation:navigation withError:error];
    }
//    print(@"==response==:%@, \nnavigation:%@",error, navigation);
    if (error.code == -999) return;
    NSURL *url = error.userInfo[@"NSErrorFailingURLKey"];
    [UIAlert(UIAlertControllerStyleAlert).title(@"加载失败").message(error.domain)
     .button(@"重试").style(UIAlertActionStyleDefault).onTappedCall(@selector(loadURL:)).byParam(url)
     .button(@"取消").style(UIAlertActionStyleCancel)
     presentWith:_controller];
}

- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error {
    if (error.code == 102) return;
    if ([self.delegate respondsToSelector:@selector(webView:didFailProvisionalNavigation:withError:)]) {
        [self.delegate webView:webView didFailProvisionalNavigation:navigation withError:error];
    } else {
        [self webView:webView didFailNavigation:navigation withError:error];
    }
}

- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(null_unspecified WKNavigation *)navigation{

//    NSString *js = @"(function() {var script = document.createElement('script');script.type = 'text/javascript';script.src = 'https://xteko.blob.core.windows.net/neo/eruda-loader.js';document.body.appendChild(script);})();";
//    [webView evaluateJavaScript:js completionHandler: nil];
    
    if ([self.delegate respondsToSelector:@selector(webView:didStartProvisionalNavigation:)]) {
        [self.delegate webView:webView didStartProvisionalNavigation:navigation];
    }

}

- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(null_unspecified WKNavigation *)navigation{
    if ([self.delegate respondsToSelector:@selector(webView:didReceiveServerRedirectForProvisionalNavigation:)]) {
        [self.delegate webView:webView didReceiveServerRedirectForProvisionalNavigation:navigation];
    }
}

- (void)webView:(WKWebView *)webView didCommitNavigation:(null_unspecified WKNavigation *)navigation{
    if ([self.delegate respondsToSelector:@selector(webView:didCommitNavigation:)]) {
        [self.delegate webView:webView didCommitNavigation:navigation];
    }


}

- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler{

    
    if ([self.delegate respondsToSelector:@selector(webView:didReceiveAuthenticationChallenge:completionHandler:)]) {
        return [self.delegate webView:webView didReceiveAuthenticationChallenge:challenge completionHandler:completionHandler];
    }
    completionHandler(NSURLSessionAuthChallengePerformDefaultHandling,challenge.proposedCredential);
}
- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView API_AVAILABLE(macosx(10.11), ios(9.0)){
    if ([self.delegate respondsToSelector:@selector(webViewWebContentProcessDidTerminate:)]) {
        [self.delegate webViewWebContentProcessDidTerminate:webView];
    }
}



- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
    if ([self.delegate respondsToSelector:@selector(webView:didFinishNavigation:)]) {
        [self.delegate webView:webView didFinishNavigation:navigation];
    }
}

- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler {
    
//    NSURL *url = navigationResponse.response.URL;
//    if ([url.absoluteString hasSuffix:@"/phone/navigate.shtml"] ||
//        [url.absoluteString hasSuffix:@"/phone/web.shtml"] ||
//        [url.absoluteString containsString:@"/phone/navigate!"]) {
//        decisionHandler(WKNavigationResponsePolicyCancel);
//        move.hidden = NO;
//    }

    
    if ([navigationResponse.response isKindOfClass:NSHTTPURLResponse.class]) {
        NSHTTPURLResponse *response = (NSHTTPURLResponse *)navigationResponse.response;
        
        print(@"==response==%ld===>>%@", (long)response.statusCode,response.URL);
        
    }
    
    objc_setAssociatedObject(webView, "current.load.url", nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

    if ([self.delegate respondsToSelector:@selector(webView:decidePolicyForNavigationResponse:decisionHandler:)]) {
        return [self.delegate webView:webView decidePolicyForNavigationResponse:navigationResponse decisionHandler:decisionHandler];
    } else {
        decisionHandler(WKNavigationResponsePolicyAllow);
    }
}

- (BOOL)webView:(WKWebView *)webView loadRequest:(NSURLRequest *)request decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    NSString *requestCookie = request.allHTTPHeaderFields[@"Cookie"];
    NSString *urlCookie = cookieFromURL(request.URL);
    if (![urlCookie isEqualToString:requestCookie]) {
        decisionHandler(WKNavigationActionPolicyCancel);
        [webView loadMutableRequest:request.mutableCopy useCookie:urlCookie];
        return YES;
    }
    return NO;
}

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    NSURL *url = navigationAction.request.URL;
    
    print(@"==response==%ld===>>%@",(long)navigationAction.navigationType,url);
    
    //    WKNavigationTypeOther 是WebView loadRequest 的结果
    if (navigationAction.targetFrame.isMainFrame) {
        // 如果是页面内激发链接 则拦截重加载 带上COOKIE
        switch (navigationAction.navigationType) {
//            case WKNavigationTypeFormResubmitted:
//            case WKNavigationTypeFormSubmitted:
            case WKNavigationTypeLinkActivated:
                if ([self webView:webView loadRequest:navigationAction.request decisionHandler:decisionHandler]) {
                    return;
                }
                break;
//                decisionHandler(WKNavigationActionPolicyCancel);
//                [webView loadMutableRequest:navigationAction.request.mutableCopy];
//                return;
            case WKNavigationTypeOther: {
                NSURL *loadURL = objc_getAssociatedObject(webView, "current.load.url");
                if (![url.absoluteString isEqualToString:loadURL.absoluteString]) {
//                    decisionHandler(WKNavigationActionPolicyCancel);
                    if ([self webView:webView loadRequest:navigationAction.request decisionHandler:decisionHandler]) {
                        return;
                    }
//                    [webView loadMutableRequest:navigationAction.request.mutableCopy];
//                    return;
                }
                break;
            }
            default:
                break;
        }
    }
    
    if ([url.scheme isEqualToString:@"tel"])
    {
        if ([UIDevice currentDevice].systemVersion.floatValue < 10.0) {
            [UIAlert(UIAlertControllerStyleAlert)
             .message(Format(@"%@",[url resourceSpecifier]))
             .button(@"取消")
             .button(@"呼叫").onTappedCall(@selector(openURL:)).byParam(url)
             presentWith:_controller];
        } else {
            [self appOpenURL:url];
        }
        
        decisionHandler(WKNavigationActionPolicyCancel);
        return;
    }
    
    
    if ([self.delegate respondsToSelector:@selector(webView:decidePolicyForNavigationAction:decisionHandler:)]) {
        return [self.delegate webView:webView decidePolicyForNavigationAction:navigationAction decisionHandler:decisionHandler];
    } else {
        decisionHandler(WKNavigationActionPolicyAllow);
    }
    
}

@end

#pragma mark - WKWebController 主类
@implementation WKWebController

- (WKWebDelegateInstance *)delegateInstance {
    if (_delegateInstance == nil) {
        _delegateInstance = [[WKWebDelegateInstance alloc] init];
        _delegateInstance.controller = self;
    }
    return _delegateInstance;
}

- (NSMutableArray<WKWebHandle *> *)handles {
    if (_handles == nil)
        _handles = [[NSMutableArray alloc] init];
    return _handles;
}


- (void)loadView {
    [super loadView];
    
    [self.webView removeFromSuperview];
    [self.progressView removeFromSuperview];
    
    UIProgressView *progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault];
    self.progressView = progressView;
    progressView.frame = CGRectMake(0, 0, CGRectGetWidth(self.view.frame), 2);
//    progressView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleBottomMargin;
    progressView.translatesAutoresizingMaskIntoConstraints = NO;
    progressView.hidden = YES;
    
    [self.view addSubview:progressView];
    self.view.backgroundColor = [UIColor whiteColor];
    
    NSLayoutConstraint *pTop = [NSLayoutConstraint constraintWithItem:progressView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.topLayoutGuide attribute:NSLayoutAttributeBottom multiplier:1 constant:0];
    NSLayoutConstraint *pLeft = [NSLayoutConstraint constraintWithItem:progressView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1 constant:0];
    NSLayoutConstraint *pRight = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:progressView attribute:NSLayoutAttributeTrailing multiplier:1 constant:0];
    NSLayoutConstraint *pHeight = [NSLayoutConstraint constraintWithItem:progressView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:2];
    
    [self.view addConstraints:@[pTop, pLeft, pRight, pHeight]];

    
    // 创建 设置
    WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
    WKUserContentController *userContent;
    if ([_delegate respondsToSelector:@selector(createUserContentController)]) {
        userContent = [_delegate createUserContentController];
    }
    if (userContent == nil) {
        userContent = [[WKUserContentController alloc] init];
    }
    config.preferences.javaScriptEnabled = YES;
    config.preferences.javaScriptCanOpenWindowsAutomatically = NO;
    
    // 添加 交互接口
    WKWebHandle *errorHandle = [[WKWebHandle alloc] initWithName:@"error" Target:self.delegateInstance Action:@selector(onJavaScriptHandleError:)];
    WKWebHandle *shareHandle = [[WKWebHandle alloc] initWithName:@"baseShare" Target:self.delegateInstance Action:@selector(onJavaScriptShare:)];
    WKWebHandle *backAppHandle = [[WKWebHandle alloc] initWithName:@"backApp" Target:self.delegateInstance Action:@selector(onJavaScriptBackApp:)];
    
    _handles = [NSMutableArray arrayWithObjects:backAppHandle, errorHandle, shareHandle, nil];
    
    if ([_delegate respondsToSelector:@selector(createWebViewHandles)]) {
        [_handles addObjectsFromArray:[_delegate createWebViewHandles]];
    }
    for (WKWebHandle *handle in self.handles) {
        [userContent addScriptMessageHandler:handle name:handle.name];
        handle.controller = self;
    }
    
    // 添加 基本接口
    NSURL *path = [[NSBundle mainBundle] URLForResource:@"WebViewBaseAPI" withExtension:@"js"];
    NSString *baseAPI = [NSString stringWithContentsOfURL:path encoding:NSUTF8StringEncoding error:nil];
    WKUserScript *apiScript = [[WKUserScript alloc] initWithSource:baseAPI injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
    [userContent addUserScript:apiScript];
    
    // 添加 注入脚本
    if ([_delegate respondsToSelector:@selector(createUserScripts)]) {
        for (WKUserScript *script in [_delegate createUserScripts]) {
            [userContent addUserScript:script];
        }
    }
    
    config.userContentController = userContent;

    WKWebView *webView;
    if ([_delegate respondsToSelector:@selector(createWebViewByFrame:configuration:)]) {
        webView = [_delegate createWebViewByFrame:self.view.bounds configuration:config];
    }
    if (!webView) {
        webView = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:config];
    }
    // 创建 WebView
//    WKWebView *webView = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:config];
    webView.UIDelegate = self.delegateInstance;
    webView.navigationDelegate = self.delegateInstance;
    webView.translatesAutoresizingMaskIntoConstraints = NO;
    webView.scrollView.bounces = NO;
    self.webView = webView;
    
    if (@available(iOS 11.0, *)) {
        webView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
    }

    
    [self.view insertSubview:webView belowSubview:progressView];
//    [self.view addSubview:webView];
    // 添加约束
    NSLayoutConstraint *top = [NSLayoutConstraint constraintWithItem:webView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.topLayoutGuide attribute:NSLayoutAttributeBottom multiplier:1 constant:0];
    NSLayoutConstraint *left = [NSLayoutConstraint constraintWithItem:webView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1 constant:0];
    NSLayoutConstraint *right = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:webView attribute:NSLayoutAttributeTrailing multiplier:1 constant:0];
    NSLayoutConstraint *bottom = [NSLayoutConstraint constraintWithItem:webView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1 constant:0];
    
    [self.view addConstraints:@[top, left, right, bottom]];
    [self listen:webView forKey:@selector(estimatedProgress) onChanged:@selector(onProgressChanged:)];
    
//    UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
//
//    [button addTarget:self
//               action:@selector(callJS)
//     forControlEvents:UIControlEventTouchUpInside];
//    
//    [button setTitle:@"  <  " forState:UIControlStateNormal];
//    
//    button.frame = CGRectMake(8, 200, 80, 32);
//    button.selected = true;
//    
//    [self.view addSubview: button];
    
}
//
//-(void)callJS {
//    [self.webView evaluateJavaScript:@"window.history.back();" completionHandler:nil];
//}

- (void)resetProgressTimer {
    [_progressTimer invalidate];
    _progressTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(onProgressTimer) userInfo:nil repeats:NO];
}

- (void)onProgressTimer {
    [self onProgressChanged:@(self.webView.estimatedProgress)];
}

- (void)onProgressChanged:(NSNumber *)progress {
    CGFloat value = progress.doubleValue;
    
    if (value >= 1) {
        self.progressView.hidden = YES;
        [self.progressView setProgress:0 animated:NO];
        _progressOffset = 0;
        [_progressTimer invalidate];
        _progressTimer = nil;
    }else {
        self.progressView.hidden = NO;
        [self.progressView setProgress:value + _progressOffset animated:YES];
        _progressOffset += 0.002;
        [self resetProgressTimer];
    }
}

- (void)appOpenURL:(NSURL *)url {
    
    [self.delegateInstance appOpenURL:url];
}

- (void)loadURL:(NSURL *)url {
    [self.webView loadURL:url];
}

- (void)viewDidLoad {
    [super viewDidLoad];
 
    self.automaticallyAdjustsScrollViewInsets = NO;
    
    if (_url) [self.webView loadURL:_url];
    // Do any additional setup after loading the view.
}
- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];

//    if (!self.navigationController.isNavigationBarHidden && self.navigationController.navigationBar.translucent) {
//        self.automaticallyAdjustsScrollViewInsets = YES;
//    }else{
//        self.automaticallyAdjustsScrollViewInsets = NO;
//    }
    
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/
@end
